<template>
  <div class="app-container">
    <el-form
      :model="queryParams"
      ref="queryForm"
      size="small"
      :inline="true"
      @submit.native.prevent
      v-show="showSearch"
      label-width="68px"
    >
      <el-form-item label="模板名称" prop="templateName">
        <el-input
          v-model="queryParams.templateName"
          placeholder="请输入模板名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
          >搜索</el-button
        >
      </el-form-item>
    </el-form>
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['template:TemplateController:add']"
          >新增</el-button
        >
      </el-col>
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
      ></right-toolbar>
    </el-row>
    <el-table v-loading="loading" :data="templateList">
      <el-table-column label="id" prop="id" width="0" v-if="false" />
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="模板名称" align="center" prop="templateName" />
      <el-table-column label="关联菜单" align="center" prop="menuNames">
        <template slot-scope="scope">
          <el-tooltip
            class="item"
            effect="dark"
            :content="scope.row.menuNames"
            placement="top"
          >
            <span v-if="scope.row.menuNames">
              {{ scope.row.menuNames.slice(0, 35) }}
              <span v-if="scope.row.menuNames.length > 35">...</span>
            </span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column label="关联用户" align="center" prop="nickNames">
        <template slot-scope="scope">
          <el-tooltip
            class="item"
            effect="dark"
            :content="scope.row.nickNames"
            placement="top"
          >
            <span v-if="scope.row.nickNames">
              {{ scope.row.nickNames.slice(0, 35) }}
              <span v-if="scope.row.nickNames.length > 35">...</span>
            </span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row, 1)"
            v-hasPermi="['template:TemplateController:edit']"
            >修改</el-button
          >
          <el-button
            size="mini"
            type="text"
            icon="el-icon-document-delete"
            @click="handleUpdate(scope.row, 2)"
            v-hasPermi="['template:TemplateController:query']"
            >详情</el-button
          >
          <el-button
            size="mini"
            type="text"
            icon="el-icon-user"
            @click="handleAddUser(scope.row)"
            v-hasPermi="['template:TemplateController:query']"
            >指定用户</el-button
          >
        </template>
      </el-table-column>
      <el-table-column label="创建信息" align="center">
        <template slot-scope="scope">
          {{ scope.row.createdBy }}<br />{{
            parseTime(scope.row.createdTime, "{y}-{m}-{d}")
          }}
        </template>
      </el-table-column>
      <el-table-column label="更新信息" align="center">
        <template slot-scope="scope">
          {{ scope.row.updateBy }}<br />{{
            parseTime(scope.row.updateTime, "{y}-{m}-{d}")
          }}
        </template>
      </el-table-column>
    </el-table>
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改模版对话框 -->
    <el-dialog
      :title="title"
      :visible.sync="openView"
      :close-on-click-modal="false"
      width="1000px"
      append-to-body
    >
      <el-form ref="form" :model="form" label-width="85px" :rules="rules">
        <el-row>
          <!-- 模板名称 -->
          <el-col :span="10">
            <el-form-item label="模板名称:" prop="templateName">
              <el-input
                v-model="form.templateName"
                placeholder="请输入模板名称"
              />
            </el-form-item>
          </el-col>

          <!-- 关联菜单 -->
          <el-col :span="12">
            <el-form-item
              label="关联菜单"
              prop="menuNames"
              class="form-item-flex"
            >
              <div class="input-button-container">
                <el-input
                  readonly
                  v-model="form.menuNames"
                  placeholder="请选择关联菜单"
                  class="flex-input"
                />
                <el-button
                  type="primary"
                  size="mini"
                  @click="openMenuDialog()"
                  v-if="decide"
                >
                  选择菜单
                </el-button>
                <el-button
                  type="danger"
                  size="mini"
                  @click="clearMenu()"
                  v-if="decide"
                >
                  清空
                </el-button>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <div ref="diagramContainer" class="diagram-container">
        <div
          v-for="(node, nodeIndex) in nodes"
          :key="node.id"
          :id="node.id"
          :style="{ top: node.y + 'px', left: '50%' }"
          class="diagram-node"
        >
          <div class="node-header">
            <i class="el-icon-user"></i> 审批人
            <el-button
              v-if="nodeIndex !== 0 && decide"
              icon="el-icon-close"
              size="mini"
              type="danger"
              class="delete-button"
              @click="deleteNode(nodeIndex)"
            ></el-button>
          </div>
          <div
            v-for="(reviewer, reviewerIndex) in node.reviewers"
            :key="reviewerIndex"
            class="node-body"
          >
            {{ reviewer.name || "未选择" }}
            <el-button
              type="primary"
              size="mini"
              style="float: right; margin-top: 5px"
              v-if="decide"
              @click="openUserDialog(nodeIndex, reviewerIndex)"
            >
              选择审核人
            </el-button>
          </div>
        </div>

        <!-- 在每个节点之间添加 + 按钮和穿过的箭头线 -->
        <div
          v-for="(node, index) in nodes"
          :key="`plus-${index}`"
          :style="{ top: node.y + 100 + 'px', left: '50%' }"
          class="plus-arrow-container"
        >
          <!-- 添加箭头线，穿过 + 按钮 -->
          <div class="arrow-line"></div>
          <el-button
            type="primary"
            icon="el-icon-plus"
            size="small"
            class="plus-button"
            @click="addNodeBelow(index)"
          ></el-button>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm()" v-if="decide"
          >确 定</el-button
        >
        <el-button @click="cancel" style="margin-left: 50px">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 选择用户 -->
    <el-dialog
      :visible.sync="openUser"
      width="700px"
      append-to-body
      :close-on-click-modal="false"
    >
      <el-form
        :model="userParam"
        ref="queryForm"
        size="small"
        :inline="true"
        v-show="showSearch"
        label-width="68px"
      >
        <el-form-item label="用户名称" prop="userName">
          <el-input
            v-model="userParam.userName"
            placeholder="请输入用户名称"
            clearable
            style="width: 150px"
            @keyup.enter.native="getUserList"
          />
        </el-form-item>
        <el-form-item label="用户昵称" prop="nickName">
          <el-input
            v-model="userParam.nickName"
            placeholder="请输入用户昵称"
            clearable
            style="width: 150px"
            @keyup.enter.native="getUserList"
          />
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            icon="el-icon-search"
            size="mini"
            @click="getUserList"
            >搜索</el-button
          >
        </el-form-item>
      </el-form>
      <el-table
        v-loading="loading"
        :data="userList"
        height="500px"
        @selection-change="handleSelectionChange"
      >
        <el-table-column label="User ID" prop="userId" width="0" v-if="false" />
        <el-table-column type="selection" width="50" align="center" />
        <el-table-column label="用户名称" align="center" prop="userName" />
        <el-table-column label="用户昵称" align="center" prop="nickName" />
        <el-table-column label="部门" align="center" prop="dept.deptName" />
      </el-table>

      <pagination
        v-show="userTotals > 0"
        :total="userTotals"
        :page.sync="userParam.pageNum"
        :limit.sync="userParam.pageSize"
        @pagination="getUserList"
      />
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="selectButton">确 定</el-button>
        <el-button @click="cancelUser" style="margin-left: 50px"
          >取消</el-button
        >
      </div>
    </el-dialog>

    <!-- 选择关联菜单-->
    <el-dialog
      :visible.sync="openMenu"
      width="450px"
      append-to-body
      :close-on-click-modal="false"
    >
      <div>
        <el-form
          :model="queryMenuParams"
          ref="queryForm"
          size="small"
          :inline="true"
          @submit.native.prevent
        >
          <el-form-item label="菜单名称" prop="menuName">
            <el-input
              v-model="queryMenuParams.menuName"
              placeholder="请输入菜单名称"
              clearable
              @keyup.enter.native="handleMenuQuery"
            />
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              icon="el-icon-search"
              size="mini"
              @click="handleMenuQuery"
              >搜索</el-button
            >
          </el-form-item>
        </el-form>
      </div>
      <el-table
        ref="table"
        v-loading="menuLoading"
        :data="menuList"
        row-key="menuId"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        :expand-row-keys="expandedKeys"
        @selection-change="handleSelectChange"
      >
        <el-table-column
          type="selection"
          width="50"
          align="center"
          :selectable="isSelectable"
        />
        <el-table-column
          prop="menuName"
          label="菜单名称"
          :show-overflow-tooltip="true"
          width="200"
        >
          <template #default="scope">
            <!-- 展开/收起文字 -->
            <span
              v-if="scope.row.children && scope.row.children.length > 0"
              class="expand-collapse-text"
              @click="toggleExpand(scope.row)"
            >
              {{ isRowExpanded(scope.row) ? "收起" : "展开" }}
            </span>
            <!-- 菜单名称 -->
            {{ scope.row.menuName }}
          </template>
        </el-table-column>

        <el-table-column prop="icon" label="图标" align="center" width="150">
          <template slot-scope="scope">
            <svg-icon :icon-class="scope.row.icon" />
          </template>
        </el-table-column>
      </el-table>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="selectMenu">确 定</el-button>
        <el-button @click="cancelMenu" style="margin-left: 50px"
          >取消</el-button
        >
      </div>
    </el-dialog>

    <!-- 指定用户 -->
    <el-dialog
      :visible.sync="openTemplateUser"
      width="700px"
      append-to-body
      :close-on-click-modal="false"
    >
      <!-- 添加已勾选用户数量显示 -->
      <div style="margin-bottom: 10px; font-size: 16px">
        已勾选
        <span style="color: red; font-weight: bold">{{
          selectedUserCount
        }}</span>
        个用户
      </div>
      <el-form
        :model="userParam"
        ref="queryForm"
        size="small"
        :inline="true"
        v-show="showSearch"
        label-width="68px"
        @submit.native.prevent
      >
        <el-form-item label="用户名称" prop="userName">
          <el-input
            v-model="userParam.userName"
            placeholder="请输入用户名称"
            clearable
            style="width: 150px"
            @keyup.enter.native="getUserListToTemplate"
          />
        </el-form-item>
        <el-form-item label="用户昵称" prop="nickName">
          <el-input
            v-model="userParam.nickName"
            placeholder="请输入用户昵称"
            clearable
            style="width: 150px"
            @keyup.enter.native="getUserListToTemplate"
          />
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            icon="el-icon-search"
            size="mini"
            @click="getUserListToTemplate"
            >搜索</el-button
          >
        </el-form-item>
      </el-form>
      <el-table
        ref="table"
        v-loading="userLoading"
        :data="userList"
        height="500px"
        @selection-change="handleUserSelectionChange"
      >
        <el-table-column label="User ID" prop="userId" width="0" v-if="false" />
        <el-table-column type="selection" width="50" align="center" />
        <el-table-column label="用户名称" align="center" prop="userName" />
        <el-table-column label="用户昵称" align="center" prop="nickName" />
        <el-table-column label="部门" align="center" prop="dept.deptName" />
      </el-table>

      <pagination
        v-show="templateUserTotals > 0"
        :total="templateUserTotals"
        :page.sync="userParam.pageNum"
        :limit.sync="userParam.pageSize"
        @pagination="getUserListToTemplate"
      />
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="templateUserButton">确 定</el-button>
        <el-button @click="cancelTemplateUser" style="margin-left: 50px"
          >取消</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  addTemplate,
  listTemplates,
  getTemplate,
  updateTemplate,
  getMenuList,
  saveTemplateUser,
} from "@/api/template/template";
import jsPlumb from "jsplumb";
import { v4 as uuidv4 } from "uuid";
import { listUser } from "@/api/system/user";
import { formatPath } from "@/api/utils/pathUtils";
export default {
  data() {
    return {
      nodes: [],
      jsPlumbInstance: null,
      // 显示搜索条件
      showSearch: true,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        templateName: "",
        id: "",
      },
      //模板弹窗
      openView: false,
      //用户弹窗
      openUser: false,
      //判断是修改还是详情
      decide: true,
      // 非单个禁用
      single: true,
      // 弹出层标题
      title: "",
      // 表单参数
      form: {
        templateId: "",
        templateName: "",
        details: [],
        menuNames: "",
        menuIds: [],
      },
      rules: {},

      userList: [],
      // 采购订单表格数据
      templateList: [],
      // 遮罩层
      loading: true,
      // 总条数
      total: 0,
      userTotals: 0,
      // 查询参数
      userParam: {
        pageNum: 1,
        pageSize: 50,
        userName: "",
        nickName: "",
      },
      // 存储当前选中的用户信息
      selectedUser: null,
      // 审核人数组，初始化一个空对象代表审核人1
      reviewers: [{ name: "" }, { userId: "" }],

      // 当前操作的审核人索引
      currentReviewerIndex: 0,
      // 菜单表格树数据
      menuList: [],
      //菜单弹窗
      openMenu: false,
      // 查询参数
      queryMenuParams: {
        menuName: "",
      },
      // 用于存储展开的行
      expandedRows: [],
      // 选中的菜单
      selectedMenus: [],
      // 默认展开的菜单ID
      expandedKeys: [],
      // 默认选中的菜单ID
      selectedKeys: [],
      menuLoading: true,

      //指定用户弹窗
      openTemplateUser: false,
      templateUserTotals: 0,
      //用户参数
      userForm: {
        templateId: "",
        userIds: [],
        userId: "",
      },
      selectedUserCount: 0,
      userLoading: true,
    };
  },
  mounted() {
    let originalPath = this.$route.path; // 当前路径
    let formattedPath = formatPath(originalPath);

    this.jsPlumbInstance = jsPlumb.jsPlumb.getInstance();
    this.jsPlumbInstance.setContainer(this.$refs.diagramContainer);

    this.jsPlumbInstance.importDefaults({
      Connector: ["Straight"],
      PaintStyle: { stroke: "#ccc", strokeWidth: 2 },
      Endpoint: "Blank",
      Anchors: ["BottomCenter", "TopCenter"],
    });
  },
  created() {
    this.getList();
    this.rules = {
      templateName: [
        {
          required: true,
          validator: this.validateTemplateName,
          trigger: "blur",
        },
      ],
      menuNames: [
        {
          required: true,
          validator: this.validateMenuNames,
          trigger: "blur",
        },
      ],
    };
  },
  methods: {
    getList() {
      this.loading = true;
      listTemplates(this.queryParams).then((response) => {
        this.templateList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.getList();
    },
    handleAdd() {
      this.reset();
      this.nodes = []; // 清空之前可能的节点
      this.addNode(); // 添加一个初始节点
      this.openView = true;
      this.title = "新增模板";
      this.decide = true;
    },
    // 取消按钮
    cancel() {
      this.reset();
      // 清空流程图节点和连接
      this.nodes = [];
      this.jsPlumbInstance.deleteEveryConnection();
      this.jsPlumbInstance.deleteEveryEndpoint();
    },
    reset() {
      if (this.$refs.form) {
        this.$refs.form.resetFields();
      }
      this.openView = false;
      this.form = {
        templateId: null,
        templateName: "",
        details: [],
        menuNames: "",
        menuIds: [],
      };
    },
    /** 修改按钮操作 */
    handleUpdate(row, type) {
      const id = row.id;
      getTemplate(id).then((response) => {
        const templateData = response;
        this.form.templateId = id;
        this.form.templateName = templateData.templateName;
        this.form.menuNames = templateData.menuNames;
        this.form.menuIds = templateData.menuIds;
        // 将数据映射到 nodes 结构中
        this.nodes = templateData.reviewers.map((reviewer, index) => ({
          id: reviewer.id,
          y: index * 160,
          reviewers: [
            {
              name: reviewer.reviewerName,
              userId: reviewer.reviewerId,
            },
          ],
        }));
        // 显示对话框
        this.openView = true;
        if (type == 1) {
          this.title = "修改模板";
          this.decide = true;
        } else {
          this.title = "模板详情";
          this.decide = false;
        }
      });
    },
    /** 新增按钮操作 */
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          const reviewerData = [];
          // 遍历每个节点
          for (let i = 0; i < this.nodes.length; i++) {
            const node = this.nodes[i];
            const userId = node.reviewers[0].userId;
            const name = node.reviewers[0].name;
            // 校验审核人 ID 是否存在
            if (!userId) {
              this.$message.error(`第 ${i + 1} 个审核人未选择`);
              return;
            }
            // 收集审核人 ID 和审核顺序
            reviewerData.push({
              reviewerId: userId,
              reviewerName: name,
              reviewOrder: i + 1, // 审核顺序
            });
          }
          this.form.details = reviewerData;
          const templateId = this.form.templateId;
          const submitAction = templateId ? updateTemplate : addTemplate;
          submitAction(this.form)
            .then((response) => {
              const actionText = templateId ? "修改" : "新增";
              this.$modal.msgSuccess(`${actionText}模版成功`);
              this.cancel(); // 关闭弹窗
              this.handleQuery(); // 刷新列表
            })
            .catch((error) => {
              //this.$message.error("提交失败，请重试！");
            });
        }
      });
    },
    // 自定义验证函数
    validateTemplateName(rule, value, callback) {
      if (!value) {
        callback(new Error("请输入模板名称"));
      } else {
        callback();
      }
    },
    // 自定义验证函数
    validateMenuNames(rule, value, callback) {
      if (!value) {
        callback(new Error("请选择关联菜单"));
      } else {
        callback();
      }
    },

    // 打开选择用户对话框
    showSelectUserDialog() {
      this.openUser = true;
      this.getUserList();
    },

    //查询所有的申请记录
    getUserList() {
      listUser(this.userParam).then((response) => {
        this.userList = response.rows;
        this.userTotals = response.total;
      });
    },
    cancelUser() {
      this.openUser = false;
    },
    // 打开选择用户对话框并指定当前操作的审核人
    openUserDialog(index, reviewerIndex) {
      // 打开用户选择对话框时，记录当前的节点和审核人索引
      this.currentNodeIndex = index;
      this.currentReviewerIndex = reviewerIndex;
      this.openUser = true;
      this.getUserList();
    },
    // 更新选中的用户信息
    handleSelectionChange(selection) {
      this.selectedUsers = selection || [];
    },
    // 确定按钮，将选中的用户赋值给当前审核人
    selectButton() {
      if (!this.selectedUsers || this.selectedUsers.length === 0) {
        this.$message.error("请选择一个用户");
        return;
      }

      if (this.selectedUsers.length > 1) {
        this.$message.error("只能选择一个用户");
        return;
      }

      // 确保只有一个用户选中
      const selectedUser = this.selectedUsers[0];
      const selectedUserName = selectedUser.nickName;

      // 校验审核人名字是否已存在
      const isDuplicate = this.nodes.some((node) =>
        node.reviewers.some((reviewer) => reviewer.name === selectedUserName)
      );

      if (isDuplicate) {
        this.$message.error("审核人名字不能重复选择");
        return;
      }
      // 获取当前节点并更新该节点的审核人信息
      const selectedNode = this.nodes[this.currentNodeIndex];
      if (selectedNode && selectedNode.reviewers) {
        this.$set(selectedNode.reviewers, this.currentReviewerIndex, {
          name: selectedUser.nickName,
          userId: selectedUser.userId,
        });
      }

      this.selectedUsers = []; // 清空选择
      this.openUser = false; // 关闭选择用户对话框
    },
    // 添加一个新的审核人
    addReviewer() {
      this.reviewers.push({ name: "" }); // 添加一个空的审核人
    },
    deleteNode(nodeIndex) {
      // 从 nodes 数组中移除指定的节点
      this.nodes.splice(nodeIndex, 1);

      // 更新节点位置和重新连接
      this.updateNodePositionsAndNames();
      this.redrawConnections();
    },
    addNode() {
      const nodeId = uuidv4();
      const newNode = {
        id: nodeId,
        reviewers: [{ name: "" }],
        y: this.nodes.length * 160,
      };
      this.nodes.push(newNode);
    },
    addNodeBelow(index) {
      const newNode = {
        id: uuidv4(),
        reviewers: [{ name: "" }],
        y: this.nodes[index].y + 160,
      };

      this.nodes.splice(index + 1, 0, newNode);
    },
    updateNodePositionsAndNames() {
      this.nodes.forEach((node, index) => {
        node.y = index * 160;
      });
    },
    redrawConnections() {
      if (!this.jsPlumbInstance) return;
      // 删除所有现有连接和端点，确保没有残留
      this.jsPlumbInstance.deleteEveryConnection();
      this.jsPlumbInstance.deleteEveryEndpoint();
    },

    //打开菜单选择
    openMenuDialog() {
      this.openMenu = true;
      this.getMenu();
    },
    getMenu() {
      this.menuLoading = true;
      getMenuList(this.queryMenuParams).then((response) => {
        this.menuList = this.handleTree(response.data, "menuId");
        this.expandedKeys =
          typeof this.form.menuIds === "string"
            ? this.form.menuIds.split(",").map((id) => parseInt(id, 10))
            : this.form.menuIds;
        this.menuLoading = false;
        this.$nextTick(() => {
          this.setDefaultSelection(); // 设置默认勾选
        });
      });
    },
    // 设置默认勾选项
    setDefaultSelection() {
      if (this.$refs.table) {
        const expandedKeysTemp = this.getExpandedKeys(
          this.menuList,
          this.expandedKeys
        ); // 获取需要展开的 keys
        this.expandedRows = [...expandedKeysTemp];
        expandedKeysTemp.forEach((id) => {
          const row = this.findRowById(this.menuList, id);
          if (row) {
            this.$refs.table.toggleRowExpansion(row, true); // 自动展开行
          }
        });
        if (Array.isArray(this.expandedKeys)) {
          this.expandedKeys.forEach((id) => {
            const row = this.findRowById(this.menuList, id);
            if (row) {
              this.$refs.table.toggleRowSelection(row, true); // 自动勾选行
            }
          });
        }
      }
    },
    // 递归查找指定ID的行
    findRowById(list, id) {
      for (const item of list) {
        if (item.menuId === id) return item;
        if (item.children) {
          const found = this.findRowById(item.children, id);
          if (found) return found;
        }
      }
      return null;
    },
    // 递归获取需要展开的 keys
    getExpandedKeys(list, keys) {
      const expanded = [];
      list.forEach((item) => {
        // 检查当前节点是否在 expandedKeys 中
        if (Array.isArray(this.expandedKeys)) {
          if (this.expandedKeys.includes(item.menuId)) {
            expanded.push(item.menuId);
          }
        }

        // 检查 children 是否有效
        if (Array.isArray(item.children) && item.children.length > 0) {
          const childExpanded = this.getExpandedKeys(item.children, keys); // 递归处理子节点
          if (childExpanded.length > 0) {
            expanded.push(item.menuId);
          }
          expanded.push(...childExpanded);
        }
      });
      return expanded;
    },

    // 选择变化回调
    handleSelectChange(selectedRows) {
      this.selectedMenus = selectedRows;
      this.selectedKeys = selectedRows.map((row) => row.menuId);
    },

    handleMenuQuery() {
      this.getMenu();
    },
    isSelectable(row) {
      return !row.children;
    },
    // 判断当前行是否已展开
    isRowExpanded(row) {
      return this.expandedRows.includes(row.menuId);
    },
    // 展开/收起逻辑
    toggleExpand(row) {
      const index = this.expandedRows.indexOf(row.menuId);
      if (index > -1) {
        // 如果已展开，则收起
        this.expandedRows.splice(index, 1);
        this.$refs.table.toggleRowExpansion(row, false);
      } else {
        // 如果未展开，则展开
        this.expandedRows.push(row.menuId);
        this.$refs.table.toggleRowExpansion(row, true);
      }
    },
    cancelMenu() {
      this.openMenu = false;
      this.menuToggleRow();
      this.expandedRows = []; // 清空展开记录
      this.selectedMenus = []; // 清空选中状态
    },
    menuToggleRow() {
      // 强制收起所有展开行
      const tableRef = this.$refs.table;
      if (tableRef) {
        this.menuList.forEach((row) => {
          tableRef.toggleRowExpansion(row, false);
        });
      }
    },
    selectMenu() {
      if (this.selectedMenus.length === 0) {
        this.$message.error("请至少选择一个菜单");
        return;
      }

      // 收集选中行的菜单 ID 和菜单名称
      const selectedMenuIds = this.selectedMenus
        .map((menu) => menu.menuId)
        .join(",");
      const selectedMenuNames = this.selectedMenus
        .map((menu) => menu.menuName)
        .join("，");

      this.form.menuNames = selectedMenuNames;
      this.form.menuIds = selectedMenuIds;
      // 手动触发验证
      if (this.$refs.form) {
        this.$refs.form.validateField("menuNames");
      }
      // 关闭对话框
      this.cancelMenu();
    },
    clearMenu() {
      this.form.menuNames = "";
      this.form.menuIds = [];
    },

    //指定用户
    handleAddUser(row) {
      this.openTemplateUser = true;
      this.queryParams.templateName = "";
      this.userParam.pageNum = 1;
      this.queryParams.id = row.id;
      // 清空表格选中状态
      this.clearSelection();
      listTemplates(this.queryParams).then((response) => {
        this.userForm.userIds = response.rows[0].userIds
          ? response.rows[0].userIds.split(",").map(Number)
          : [];
        this.userForm.templateId = row.id;
        this.queryParams.id = "";
        this.getUserListToTemplate();
      });
    },
    getUserListToTemplate() {
      this.userLoading = true;
      listUser(this.userParam).then((response) => {
        this.userList = response.rows;
        this.templateUserTotals = response.total;

        // 使用 this.userForm.userIds 进行自动勾选
        const initialUserIds = this.userForm.userIds || [];
        const formattedUserIds = Array.isArray(initialUserIds)
          ? initialUserIds.map((id) => String(id).replace(/^0+/, ""))
          : String(initialUserIds)
              .split(",")
              .map((id) => id.replace(/^0+/, ""));
        this.userLoading = false;
        this.$nextTick(() => {
          this.autoSelectUsers(formattedUserIds);
        });
      });
    },
    // 自动勾选用户
    autoSelectUsers(userIds) {
      if (this.$refs.table) {
        this.userList.forEach((user) => {
          // 比较时处理 userId 的格式差异
          const normalizedUserId = String(user.userId).replace(/^0+/, ""); // 去除前导零
          if (userIds.includes(normalizedUserId)) {
            this.$refs.table.toggleRowSelection(user, true); // 勾选用户
          }
        });
        // 排序，将选中的用户放到前面
        this.userList.sort((a, b) => {
          const aSelected = userIds.includes(
            String(a.userId).replace(/^0+/, "")
          );
          const bSelected = userIds.includes(
            String(b.userId).replace(/^0+/, "")
          );
          return bSelected - aSelected; // 选中的用户排在前面
        });
      }
    },
    //关闭指定用户
    cancelTemplateUser() {
      // 清空表格选中状态
      this.clearSelection();
      this.openTemplateUser = false;
      this.userForm = {
        templateId: "",
        userIds: [],
        userId: "",
      };
    },
    //用户列复选框
    handleUserSelectionChange(selectedRows) {
      const currentPageIds = selectedRows.map((row) => row.userId); // 当前页选中的用户 ID
      // 去掉当前页的所有 ID
      this.userForm.userIds = this.userForm.userIds.filter(
        (id) => !this.userList.some((user) => user.userId === id)
      );
      // 排序，将选中的用户放到前面
      this.userList.sort((a, b) => {
        const aSelected = this.userForm.userIds.includes(a.userId);
        const bSelected = this.userForm.userIds.includes(b.userId);
        return bSelected - aSelected; // 选中的用户排在前面
      });
      // 添加当前页选中的 ID
      this.userForm.userIds.push(...currentPageIds);
      this.selectedUserCount = this.userForm.userIds.length;
    },
    //新增/修改指定用户
    templateUserButton() {
      if (this.userForm.userIds.length === 0) {
        this.$message.error("请至少选择一个用户");
        return;
      }
      if (!this.userForm.templateId) {
        this.$message.error("获取模板ID失败，请重新操作");
        return;
      }
      this.userForm.userId = this.userForm.userIds.join(",");
      saveTemplateUser(this.userForm).then((response) => {
        this.$modal.msgSuccess(`指定用户模版成功`);
        this.cancelTemplateUser();
        this.getList();
      });
    },
    // 清空表格选中状态
    clearSelection() {
      this.$nextTick(() => {
        if (this.$refs.table) {
          this.$refs.table.clearSelection();
        }
      });
    },
  },
};
</script>

<style scoped>
::v-deep .el-dialog__body {
  padding-top: 0px !important;
}
.diagram-container {
  width: 100%;
  height: 630px;
  position: relative;
  overflow: auto;
  padding: 20px;
}
.diagram-node {
  width: 320px;
  background-color: #fff; /* 主体背景色 */
  color: black;
  border-radius: 5px;
  text-align: center;
  position: absolute;
  cursor: pointer;
  user-select: none;
  transform: translateX(-50%);
  padding-bottom: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* 添加阴影 */

  /* 创建顶部的橙色条 */
  border-left: 1px solid #ddd; /* 左边浅灰色边框 */
  border-right: 1px solid #ddd; /* 右边浅灰色边框 */
  border-bottom: 1px solid #ddd; /* 底部浅灰色边框 */
}

.node-header {
  background-color: #f7941d; /* 橙色背景 */
  color: white;
  padding: 6px;
  border-radius: 5px 5px 0 0; /* 顶部圆角 */
  font-size: 14px;
  text-align: left; /* 标题居左 */
  padding-left: 15px; /* 标题左侧空隙 */
}
.node-body {
  padding: 10px;
  font-size: 16px;
  text-align: left; /* 标题居左 */
  padding-left: 15px; /* 标题左侧空隙 */
}
.plus-arrow-container {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: translateX(-50%);
}
.plus-button {
  margin: 0 0;
  z-index: 2;
}
.arrow-line {
  width: 2px;
  height: 70px;
  background-color: #ccc;
  position: absolute;
  top: -15px; /* 调整位置，使其穿过+按钮 */
  z-index: 1; /* 确保箭头线在+按钮后面 */
}
.arrow-line::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid #ccc;
  position: absolute;
  bottom: -5px; /* 将箭头定位在箭头线的底部 */
  left: -4px; /* 居中 */
}
.el-button--small {
  border-radius: 10px;
}
.node-header {
  position: relative;
  padding-right: 25px; /* 为右上角的删除按钮腾出空间 */
}
.delete-button {
  position: absolute;
  top: 3px;
  right: 5px;
  z-index: 10;
  color: #fff;
  background-color: #ff4d4f; /* 红色背景色，表示删除操作 */
  border: none;
}
.form-item-flex .input-button-container {
  display: flex; /* 启用 flex 布局 */
  align-items: center; /* 垂直居中对齐 */
}
.form-item-flex .flex-input {
  flex: 1; /* 输入框填满剩余空间 */
  margin-right: 10px; /* 与按钮之间的间距 */
}
.expand-collapse-text {
  color: #409eff;
  cursor: pointer;
  margin-right: 8px;
}
.expand-collapse-text:hover {
  text-decoration: underline;
}
</style>
